﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace CommonLib.Pattern.FSM
{
	public interface IFSM
	{
		string Key { get; }
		IState CurState { get; }
		IState Default { get; }
		Dictionary<string, IState> StatesDic { get; }

		void BeginMachine();
		void EndMachine();
		void UpdateMachine(float deltaTime);

		void AddState(IState state);
		void RemoveState(IState state);
		void SetState(IState state);
		IState GetStateByName(string name);
	}

	public class FSMMachineBase : IFSM
	{
		public string Key => machineKey;

		public IState CurState => curState;

		public IState Default => defaultState;

		public Dictionary<string, IState> StatesDic => statesDic;

		
		/// <summary>
		/// 开启状态机
		/// </summary>
		public void BeginMachine()
		{
			curState?.EnterState(null);
		}

		/// <summary>
		/// 关闭状态机
		/// </summary>
		public void EndMachine()
		{
			curState?.ExitState(null);
		}

		/// <summary>
		/// 获取指定的状态
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public IState GetStateByName(string name)
		{
			if(statesDic.TryGetValue(name, out IState state))
				return state;	
			else
			{
				Debug.Log($"Not Find State [{name}]");
				return null;
			}
		}
		/// <summary>
		/// 添加状态
		/// </summary>
		/// <param name="state"></param>
		public void AddState(IState state)
		{
			if (statesDic.ContainsKey(state.Key))
				Debug.LogError($"Machine [{machineKey}] Already have State [{state.Key}]");
			else
			{
				state.SetMachine(this);
				statesDic.Add(state.Key, state);
			}
		}
		/// <summary>
		/// 移除状态
		/// </summary>
		/// <param name="state"></param>
		public void RemoveState(IState state)
		{
			if (statesDic.ContainsKey(state.Key))
				statesDic.Remove(state.Key);
		}
		/// <summary>
		/// 设置状态机的当前状态
		/// </summary>
		/// <param name="state"></param>
		public void SetState(IState state)
		{
			if (null == state)
				return;
			/* Only Set Current
			if (null != curState)
			{
				curState.ExitState(state);
				state.EnterState(curState);
			}
			else
				state.EnterState(null);
				*/
			curState = state;
		}
		/// <summary>
		/// 状态机更新当前状态
		/// </summary>
		/// <param name="deltaTime"></param>
		public void UpdateMachine(float deltaTime)
		{
			curState.UpdateState(deltaTime);
		}

		public FSMMachineBase(string _name, IState _defaultState)
		{
			this.defaultState = _defaultState;
			this.machineKey = _name;
			statesDic = new Dictionary<string, IState>();
			if (null != _defaultState)
				statesDic.Add(_defaultState.Key, _defaultState);
			curState = _defaultState;
		}
		protected string machineKey ="";
		protected IState curState;
		protected IState defaultState;
		protected Dictionary<string, IState> statesDic;
		
	}
}